package com.yhos.platform.oopston.core.mybatis;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.enums.DBType;
import com.baomidou.mybatisplus.mapper.LogicSqlInjector;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.plugins.PerformanceInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import com.baomidou.mybatisplus.spring.boot.starter.MybatisPlusProperties;
import com.baomidou.mybatisplus.spring.boot.starter.SpringBootVFS;
import org.apache.ibatis.plugin.Interceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;

@Configuration
@EnableTransactionManagement
@EnableConfigurationProperties(MybatisPlusProperties.class)
public class MyBatisConfig {

    @Autowired
    private MybatisPlusProperties mybatisPlusProperties;

    @Autowired
    private DruidDataSource druidDataSource;

    @Autowired(required = false)
    private Interceptor[] interceptors;

    @Bean
    public PerformanceInterceptor performanceInterceptor() {
        return new PerformanceInterceptor();
    }

    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor page = new PaginationInterceptor();
        page.setDialectType("mysql");
        return page;
    }

    @Bean
    public MybatisSqlSessionFactoryBean createSqlSessionFactoryBean() throws IOException {
        MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(druidDataSource);
        sqlSessionFactoryBean.setVfs(SpringBootVFS.class);
        if (StringUtils.hasText(this.mybatisPlusProperties.getConfigLocation())) {
            sqlSessionFactoryBean.setConfigLocation(new ClassPathResource(this.mybatisPlusProperties.getConfigLocation()));
        }
        sqlSessionFactoryBean.setConfiguration(mybatisPlusProperties.getConfiguration());
        if (!ObjectUtils.isEmpty(this.interceptors)) {
            sqlSessionFactoryBean.setPlugins(this.interceptors);
        }

        GlobalConfiguration globalConfig = new GlobalConfiguration();
        globalConfig.setSqlInjector(new LogicSqlInjector());
        globalConfig.setDbType(DBType.MYSQL.name());
        globalConfig.setIdType(0);
        globalConfig.setDbColumnUnderline(true);
        globalConfig.setRefresh(true);
        globalConfig.setTablePrefix("tb_");
//        globalConfig.setCapitalMode(true);
        sqlSessionFactoryBean.setGlobalConfig(globalConfig);
//        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
//        configuration.setMapUnderscoreToCamelCase(true);
//        configuration.setCacheEnabled(true);//全局启用或禁用延迟加载。当禁用时，所有关联对象都会即时加载
//        configuration.setLazyLoadingEnabled(true);//当启用时，有延迟加载属性的对象在被调用时将会完全加载任意属性。否则，每种属性将会按需要加载
//        configuration.setAggressiveLazyLoading(true);//是否允许单条sql 返回多个数据集 (取决于驱动的兼容性) default:true
//        configuration.setUseColumnLabel(true);//允许JDBC 生成主键。需要驱动器支持。如果设为了true，这个设置将强制使用被生成的主键，有一些驱动器不兼容不过仍然可以执行
//        configuration.setUseGeneratedKeys(true);
//        configuration.setAutoMappingBehavior(AutoMappingBehavior.PARTIAL);//指定 MyBatis 如何自动映射 数据基表的列 NONE：不隐射 PARTIAL:部分 FULL:全部
//        configuration.setDefaultExecutorType(ExecutorType.SIMPLE);//配置和设定执行器，SIMPLE 执行器执行其它语句。REUSE 执行器可能重复使用prepared statements 语句，BATCH执行器可以重复执行语句和批量更新。
//        configuration.setLocalCacheScope(LocalCacheScope.SESSION);
//        configuration.setJdbcTypeForNull(JdbcType.NULL);//设置但JDBC类型为空时,某些驱动程序 要指定值,default:OTHER，插入空值时不需要指定类型
//        sqlSessionFactoryBean.setConfiguration(configuration);

        if (!ObjectUtils.isEmpty(this.mybatisPlusProperties.resolveMapperLocations())) {
            sqlSessionFactoryBean.setMapperLocations(this.mybatisPlusProperties.resolveMapperLocations());
        }
        if (StringUtils.hasLength(this.mybatisPlusProperties.getTypeAliasesPackage())) {
            sqlSessionFactoryBean.setTypeAliasesPackage(this.mybatisPlusProperties.getTypeAliasesPackage());
        }
        if (StringUtils.hasLength(this.mybatisPlusProperties.getTypeHandlersPackage())) {
            sqlSessionFactoryBean.setTypeHandlersPackage(this.mybatisPlusProperties.getTypeHandlersPackage());
        }
        return sqlSessionFactoryBean;
    }

    @Bean
    public DataSourceTransactionManager createDataSourceTransactionManager() {
        DataSourceTransactionManager manager = new DataSourceTransactionManager();
        manager.setDataSource(druidDataSource);
        return manager;
    }

}
